package org.reborn.engine.input

import org.reborn.utils.PropertyUtil

object KeyboardKey extends Enumeration{
  type KeyboardKey = Value
  val A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
    _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, 
    Tab, Left_Shift, Right_Shift, Left_Ctrl, Right_Ctrl, Left_Alt, Right_Alt, 
    Space, |, \, /, Semicolon, Quote, -, Equals,
    Comma, Period, Left_Square_Bracket, Right_Square_Bracket,
    Esc, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, 
    Num_Pad_0, Num_Pad_1, Num_Pad_2, Num_Pad_3, Num_Pad_4, 
    Num_Pad_5, Num_Pad_6, Num_Pad_7, Num_Pad_8, Num_Pad_9,
    Num_Pad_+, Num_Pad_-, Num_Pad_*, Num_Pad_/, Num_Pad_Period, Num_Pad_Enter,
    Left, Right, Up, Down, Insert, Delete, Home, End, Page_Up, Page_Down = Value
}

/**
 * An input device that makes keyboard input available.
 */
trait Keyboard extends InputDevice{
  import KeyboardKey._
  
  /**
   * @param key the key to query the "keydown" state for
   * @return true if the key is down, false otherwise
   */
  def keydown(key:String):Boolean = {
	Keyboard.stringToKeyMap.get(key).foreach{(keyboardKey) =>
	  return keydown(keyboardKey)
	}
	return false
  }
  
  /**
   * @param key the key to query the "keydown" state for
   * @return true if the key is down, false otherwise
   */
  def keydown(key:KeyboardKey):Boolean
  
  /**
   * @param key the key representing the underlying ButtonComponent 
   * @return the ButtonComponent corresponding to the specified key if it exists
   */
  def getKeyComponent(key:String):Option[ButtonComponent]= {
	Keyboard.stringToKeyMap.get(key).foreach{(keyboardKey) =>
	  return getKeyComponent(keyboardKey)
	}
	return None
  }
  
  /**
   * @param key the key representing the underlying ButtonComponent 
   * @return the ButtonComponent corresponding to the specified key if it exists
   */
  def getKeyComponent(key:KeyboardKey):Option[ButtonComponent]
}

object Keyboard{
  private val KEYBOARD_PROPS = "org/reborn/engine/input/keyboard.properties" 
  
  val Keys = KeyboardKey
  
  lazy val stringToKeyMap:Map[String,Keys.KeyboardKey] = {
	var map:Map[String,Keys.KeyboardKey] = Map()
	
	PropertyUtil.ReadProperties(KEYBOARD_PROPS).foreach{props =>
	  for((key,value) <- props){ 
	 	val upperKey = key.toUpperCase
	 	val lowerKey = key.toLowerCase
	 	val noUnderscoreKey = key.replaceAll("_","")
	 	val noUnderscoreUpper = noUnderscoreKey.toUpperCase
	 	val noUnderscoreLower = noUnderscoreKey.toLowerCase
	    
	 	val compKey = Keys.withName(value)
	 	map+=(key -> compKey)
	    if(!map.contains(upperKey)) map+=(upperKey -> compKey)
	    if(!map.contains(lowerKey)) map+=(lowerKey -> compKey)
	    if(!map.contains(noUnderscoreKey)) map+=(noUnderscoreKey -> compKey)
	    if(!map.contains(noUnderscoreUpper)) map+=(noUnderscoreUpper -> compKey)
	    if(!map.contains(noUnderscoreLower)) map+=(noUnderscoreLower -> compKey)
	  }	
	}
	map
  }
}
